// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// I [author] rhyme_lph
// v [email]  rhymelph@gmail.com
// G [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:dio/src/response.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/invoice_entity.dart';
import 'package:finance_app/src/http_service/http_invoice_service.dart';
import 'package:finance_app/src/mixin/check_plan_mixin.dart';
import 'package:finance_app/src/mixin/refresh_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/widgets/bottom_sheet/delete_info_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/page/dashboard/invoice/invoice_number_page.dart';
import 'dart:async';

class InvoiceNumberProvider extends BaseProvider<List<InvoiceEntity>>
    with
        SearchDataListMixin,
        RefreshMixin<List<InvoiceEntity>, List<InvoiceEntity>>,
        CheckPlanMixin {
  InvoiceEntity invoice;
  List<InvoiceEntity> invoices = [];
  bool isMultiple;

  int filterIssueTo;

  String keyword;

  @override
  Future get dataFuture => HttpInvoiceService.invoiceList(page,
      issue_to: filterIssueTo, keyword: keyword);

  @override
  void initState() {
    super.initState();
  }

  void onNavAddInvoice() async {
    if (isPlanExpired()) return;
    final result =
        await Routes.navigateTo(RouterGenProviders.newInvoicePage, params: {
      'isSelectMode': true,
    });
    if (result != null) {
      if (result is InvoiceEntity) {
        if (filterIssueTo != null && filterIssueTo != result.contactId) {
          return;
        }
      }
      if (isMultiple == true) {
        invoices.add(result);
        data.add(result);
        update();
      } else {
        invoice = result;
        onDone();
      }
    }
  }

  void onSelect(InvoiceEntity item1) {
    if (isMultiple == true) {
      final result = invoices.firstWhere((element) => element.id == item1.id,
          orElse: () => null);
      if (result != null) {
        invoices.removeWhere((element) => element.id == item1.id);
      } else {
        invoices.add(item1);
      }
      update();
    } else {
      invoice = item1;
      onDone();
    }
  }

  void onDone() {
    obtainContext?.call((context) {
      if (isMultiple == true) {
        Navigator.of(context).pop(invoices);
      } else {
        Navigator.of(context).pop(invoice);
      }
    });
  }

  void onCancel() {
    obtainContext?.call((context) {
      Navigator.of(context).pop();
    });
  }

  @override
  void searchRefreshData(string) async {
    keyword = string;
    page = 1;
    await post(refreshFuture, autoHandler: AutoHandler.Toast,
        onSuccess: (result) {
      data = getFromRequestResult(result, true);
      update();
    }, onFinally: () {
      if (data == null) {
        data = [];
      }
      update();
    });
  }

  @override
  FutureOr<List<InvoiceEntity>> transformData(
      List<InvoiceEntity> d, bool isCache) {
    List<InvoiceEntity> updateInvoices = [];
    for (final item in d) {
      final oldItem = invoices.firstWhere((element) => element.id == item.id,
          orElse: () => null);
      if (oldItem != null) {
        updateInvoices.add(item);
      }
    }
    invoices = updateInvoices;
    return super.transformData(d, isCache);
  }

  @override
  List<InvoiceEntity> get dataList => data;

  @override
  List<InvoiceEntity> getFromRequestResult(Response result, bool isRefresh) {
    return getEntityFromResult(result);
  }

  @override
  Future get refreshFuture => dataFuture;
}
